import type { MirrorWebsiteFile } from "@common/spider-types";
import semver from "semver";
import type { ToolInstallVersionItem } from "../common/types";
import { MirrorDataFilter } from "../mirror/filter";
import { BaseEnvMirror } from "../mirror/mirror";
import { GolangBitnessFilter } from "./golang-mirror";
import { getGolangArch, getGolangPlatform } from "./utils.ts";

class VersionFilter extends MirrorDataFilter {
  constructor() {
    super("版本");
  }

  protected filter0(versions: ToolInstallVersionItem[]): ToolInstallVersionItem[] {
    return versions.filter(it => it.version1 === this.value);
  }
}

export class GolangAliyunMirror extends BaseEnvMirror {
  private readonly _versionFilter = new VersionFilter();

  constructor() {
    super({
      id: "golang.aliyun",
      name: "阿里云",
      url: "https://mirrors.aliyun.com/golang/",
      website: "https://mirrors.aliyun.com/golang/",
    });
  }

  protected getFilters0(): MirrorDataFilter[] {
    return [this._versionFilter, new GolangBitnessFilter()];
  }

  protected getDownloadList0(files: MirrorWebsiteFile[]): ToolInstallVersionItem[] {
    const versionList: ToolInstallVersionItem[] = [];
    const platform = getGolangPlatform();
    const arch = getGolangArch();

    const versionSet = new Set<string>();
    for (let it of files) {
      if (!it.name.startsWith("go")) continue;
      if (it.name.includes("src")) continue; // 源码包

      // https://mirrors.aliyun.com/golang/go1.20rc1.windows-amd64.zip
      // https://mirrors.aliyun.com/golang/go1.24.5.windows-amd64.zip
      const [token0, token1] = it.name.split("-");
      let i = token0.lastIndexOf(".");
      const version = token0.substring(2, i);
      if (/[a-zA-Z]/.test(version)) continue; // 含字母的版本为测试版

      const itemPatform = token0.substring(i + 1);

      i = token1.indexOf(".");
      const itemArch = token1.substring(0, i);
      const ext = token1.substring(i);
      const isArchive = ext === ".zip" || ext === ".tar.gz";

      if (isArchive && platform === itemPatform && arch.includes(itemArch)) {
        const bitness = itemArch === "amd64" ? 64 : 32;
        // 有些只有两位的版本号,补足三位方便排序
        const [major, minor, patch = "0"] = version.split(".");
        const version1 = `${major}.${minor}`;
        const version2 = `${major}.${minor}.${patch}`;

        versionSet.add(version1);
        versionList.push({
          id: `golang-${it.name}`,
          name: it.name,
          version,
          url: `${this.url}/${it.name}`,
          bitness,
          version1,
          version2,
          date: it.date,
          size: it.size,
        });
      }
    }

    versionList.sort((a, b) => semver.compare(b.version2!, a.version2!));

    // 设置版本号过滤器
    const versions = [...versionSet];
    versions.sort((a, b) => semver.compare(b + ".0", a + ".0"));
    this._versionFilter.value = versions[0];
    this._versionFilter.setDataSource(versions.map(it => ({ value: it })));

    return versionList;
  }
}
